﻿/*
 * WangXin 2012年3月9日 12:17:39
 */
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Windows.Input;
using Apps.Yunwei.YunWeiService;
using Microsoft.Expression.Interactivity.Core;
using QDP.Platform.ObjService;
using QDP.Platform.Services;
namespace Apps.Yunwei.ViewModels
{
    public class AuthorityViewModel : INotifyPropertyChanged
    {
        private RoleObject selectedRole;
        private UserObject selectedUser;
        private object selectedItem;
        private string userID;
        private bool roleIsBusy;
        private bool topicIsBusy;
        private bool userIsBusy;
        private Dictionary<string, string> configs;
        public AuthorityViewModel()
        {
            this.Roles = new ObservableCollection<RoleObject>();
            this.Datas = new ObservableCollection<TopicItemObject>();
            this.Users = new ObservableCollection<UserSelectable>();
            this.SelectedCommand = new ActionCommand(this.Selected);
            this.RefreshRoleCommand = new ActionCommand(this.RefreshRole);
            this.RefreshTopicCommand = new ActionCommand(this.RefreshTopic);
            this.RefreshUserCommand = new ActionCommand(this.RefreshUser);
            this.SaveUserCommand = new ActionCommand(this.SaveUser);
            this.SaveTopicCommand = new ActionCommand(this.SaveTopic);
        }
        public void SetConfig(Dictionary<string, string> cfgs)
        {
            this.configs = cfgs;
            this.Initialize();
            this.RefreshTopic();
            this.RefreshUser();
            this.RefreshRole();
        }

        private void Initialize()
        {
            dynamic userinfo = Q.DataManager.GetUserData();
            userID = userinfo.ID;
            Client = ServiceLoader.CreateWCFClient<NorOpSvClient>(configs["CC_URL"]);
            Client.GetAppsCompleted += Client_GetAppsCompleted;
            Client.GetRolesCompleted += Client_GetRolesCompleted;
            Client.GetUsersCompleted += Client_GetUsersCompleted;
            Client.GetUserAuthoritysCompleted += GetUserAuthoritysCompleted;
            Client.GetAppAuthoritysCompleted += Client_GetAppAuthoritysCompleted;

            Client.AssignRoleAppCompleted += Client_AssignRoleAppCompleted;
            Client.AssignUserRoleCompleted += Client_AssignUserRoleCompleted;

            Client.GetServicesCompleted += Client_GetServicesCompleted;
        }

        void Client_GetServicesCompleted(object sender, GetServicesCompletedEventArgs e)
        {
            if (e.Error != null)
            {
                this.ShowMessage(e.Error.Message,e.Error.ToString());
            }
            else
            {
                FillTopicTree(e.Result);
            }
        }
        void Client_GetAppsCompleted(object sender, GetAppsCompletedEventArgs e)
        {
            this.TopicIsBusy = false;
            if (e.Error != null)
            {
                this.ShowMessage(e.Error.Message,e.Error.ToString());
            }
            else
            {
                FillTopicTree(e.Result);
                Client.GetServicesAsync();
            }
        }

        void Client_AssignUserRoleCompleted(object sender, AssignUserRoleCompletedEventArgs e)
        {
            UserIsBusy = false;
            if (e.Error != null)
            {
                this.ShowMessage(e.Error.Message,e.Error.ToString());
            }
        }

        void Client_AssignRoleAppCompleted(object sender, AssignRoleAppCompletedEventArgs e)
        {
            TopicIsBusy = false;
            if (e.Error != null)
            {
                this.ShowMessage(e.Error.Message,e.Error.ToString());
            }
        }

        void Client_GetAppAuthoritysCompleted(object sender, GetAppAuthoritysCompletedEventArgs e)
        {
            TopicIsBusy = false;
            if (e.Error != null)
            {
                this.ShowMessage(e.Error.Message,e.Error.ToString());
                return;
            }
            bool t = false;
            foreach (var dir in this.Datas)
            {
                FlagSelected(dir.Children, e.Result.ToArray(), out t);
            }
        }

        void GetUserAuthoritysCompleted(object sender, GetUserAuthoritysCompletedEventArgs e)
        {
            UserIsBusy = false;
            if (e.Error != null)
            {
                this.ShowMessage(e.Error.Message,e.Error.ToString());
                return;
            }

            var userIDs = e.Result;
            foreach (var user in this.Users)
            {
                user.Selected = false;
                foreach (var userID in userIDs)
                {
                    if (userID == user.ID)
                    {
                        user.Selected = true;
                        continue;
                    }
                }
            }
        }

        void Client_GetUsersCompleted(object sender, GetUsersCompletedEventArgs e)
        {
            if (e.Error != null)
            {
                this.ShowMessage(e.Error.Message,e.Error.ToString());
                return;
            }
            UserIsBusy = false;
            this.Users.Clear();
            foreach (var user in e.Result.OrderBy(p => p.Code))
            {
                this.Users.Add(new UserSelectable(user));
            }
        }

        void Client_GetRolesCompleted(object sender, GetRolesCompletedEventArgs e)
        {
            if (e.Error != null)
            {
                this.ShowMessage(e.Error.Message,e.Error.ToString());
                return;
            }
            RoleIsBusy = false;

            this.Roles.Clear();
            foreach (var v in e.Result.OrderBy(p => p.Code))
            {
                this.Roles.Add(v);
            }
            //this.Roles.Add(new RoleObject()
            //{
            //    Caption = "创建新角色",
            //    Code = "CreateNew",
            //    ID = flag
            //});
        }
        // 获取选中的权限

        private TopicItemObject GetDataNode(string caption)
        {
            string[] tags = caption.Split('\\');
            TopicItemObject parentNode = null;
            foreach (var tag in tags)
            {
                if (parentNode == null && Datas.Any(p => p.Caption == tag))
                {
                    parentNode = Datas.First(p => p.Caption == tag);
                }
                else if (parentNode != null && parentNode.Children.Any(p => p.Caption == tag))
                {
                    parentNode = parentNode.Children.First(p => p.Caption == tag);
                }
                else
                {
                    var temp = new TopicItemObject()
                    {
                        Caption = tag,
                        ImageUrl1 = "/Resource/0.png",
                        Background = "Transparent",
                        Parent = parentNode,
                    };

                    if (parentNode == null)
                    {
                        temp.Tags = tag;
                        Datas.Add(temp);
                    }
                    else
                    {
                        temp.Tags = parentNode.Tags + "\\" + tag;
                        parentNode.Children.Add(temp);
                    }

                    parentNode = temp;
                }
            }
            return parentNode;
        }
        private void FillTopicTree(IList items)
        {
            TopicItemObject treeItem = null;
            foreach (dynamic item in items)
            {
                var parent = GetDataNode(item.Tags);
                treeItem = new TopicItemObject()
                {
                    Caption = item.Caption,
                    ID = item.ID,
                    ImageUrl1 = item.Icon1,
                    Tags = item.Tags
                };
                if (string.IsNullOrEmpty(item.Bgc) == false)
                {
                    treeItem.Background = item.Bgc;
                }

                if (item is ServiceObject)
                    treeItem.Type = TopicItemType.Service;
                else
                    treeItem.Type = TopicItemType.App;
                treeItem.Parent = parent;
                parent.Children.Add(treeItem);
            }
        }

        private ObservableCollection<string> GetSelectedApps(IList<TopicItemObject> datas)
        {
            return this.GetSelected(TopicItemType.App,datas);
        }
        private ObservableCollection<string> GetSelectedServices(IList<TopicItemObject> datas)
        {
            return this.GetSelected(TopicItemType.Service, datas);
        }

        private ObservableCollection<string> GetSelected(TopicItemType type, IList<TopicItemObject> datas)
        {
            var result = new ObservableCollection<string>();
            foreach (var data in datas)
            {
                if (data.Type == TopicItemType.Directory)
                {
                    foreach (var item in GetSelected(type, data.Children))
                    {
                        result.Add(item);
                    }
                }
                else if (data.Type == type)
                {
                    if (data.IsChecked)
                    {
                        result.Add(data.ID);
                    }
                }
            }
            return result;
        }

        private void FlagSelected(IList<TopicItemObject> datas , string[] auth , out bool parentChecked)
        {
            parentChecked = false;
            foreach (var data in datas)
            {
                if (auth.Any(p => p == data.ID))
                {
                    parentChecked = true;
                    data.IsChecked = true;
                }
                else
                {
                    data.IsChecked = false;
                }
                if (data.Type == TopicItemType.Directory)
                {
                    var parentCheckedc = false;
                    FlagSelected(data.Children, auth, out parentCheckedc);
                    if (parentCheckedc)
                    {
                        parentChecked = true;
                        data.IsChecked = true;
                    }
                }
            }
        }
        // 选中角色功能处理流程
        private void Selected(object selectedItem)
        {
            if (selectedItem is UserObject)
            {
                this.selectedUser = selectedItem as UserObject;
            }
            else
            {
                this.selectedRole = selectedItem as RoleObject;

                Client.GetUserAuthoritysAsync(selectedRole.ID);
                Client.GetAppAuthoritysAsync(selectedRole.ID);
            }
        }

        // 刷新用户功能处理流程
        private void RefreshUser()
        {
            this.UserIsBusy = true;
            Client.GetUsersAsync();
        }
        // 刷新角色功能处理流程
        private void RefreshRole()
        {
            this.RoleIsBusy = true;
            Client.GetRolesAsync();
        }
        const string flag = "CREATE_NEW";
        // 保存用户关系功能处理流程
        private void SaveUser()
        {
            if (selectedRole == null) return;
            this.UserIsBusy = true;
            if (Client != null)
            {
                var userIDs = new ObservableCollection<string>();
                foreach (var user in this.Users)
                {
                    if (user.Selected)
                        userIDs.Add(user.ID);
                }
                Client.AssignUserRoleAsync(selectedRole.ID, userIDs);
            }
            else
            {
                this.ShowMessage("数据请求服务地址不存在，请检查参数设置或与管理员联系。");
            }
        }

        // 刷新专题功能处理流程
        private void RefreshTopic()
        {
            this.TopicIsBusy = true;
            Datas.Clear();
            Client.GetAppsAsync();
        }

        NorOpSvClient Client = null;

        // 保存专题关系功能处理流程
        private void SaveTopic()
        {
            if (selectedRole == null) return;
            TopicIsBusy = true;
            if (Client != null)
            {
                Client.AssignRoleAppAsync(selectedRole.ID, this.GetSelectedApps(this.Datas));
                Client.AssignRoleServiceAsync(selectedRole.ID, this.GetSelectedServices(this.Datas));
            }
            else
                this.ShowMessage("数据请求服务地址不存在，请检查参数设置或与管理员联系。");
        }

        #region INotifyPropertyChanged
        public event PropertyChangedEventHandler PropertyChanged;

        private void NotifyPropertyChanged(String info)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(info));
            }
        }
        #endregion

        // 表示用户清单是否正在工作
        public bool UserIsBusy
        {
            get { return userIsBusy; }
            set
            {
                if (userIsBusy != value)
                {
                    userIsBusy = value;
                    NotifyPropertyChanged("UsersIsBusy");
                }
            }
        }
        // 表示角色清单是否正在工作
        public bool RoleIsBusy
        {
            get { return roleIsBusy; }
            set
            {
                if (roleIsBusy != value)
                {
                    roleIsBusy = value;
                    NotifyPropertyChanged("TreeIsBusy");
                }
            }
        }
        // 表示专题结构是否正在工作
        public bool TopicIsBusy
        {
            get { return topicIsBusy; }
            set
            {
                if (topicIsBusy != value)
                {
                    topicIsBusy = value;
                    NotifyPropertyChanged("DetailIsBusy");
                }
            }
        }
        // 表示当前选中的角色信息
        public object SelectedItem
        {
            get { return this.selectedItem; }
            set
            {
                if (this.selectedRole != value)
                {
                    this.selectedItem = value;
                    this.Selected(value);
                    NotifyPropertyChanged("SelectedRole");
                }
            }
        }
        // 角色清单
        public ObservableCollection<RoleObject> Roles { get; set; }
        //专题结构
        public ObservableCollection<TopicItemObject> Datas { get; set; }
        // 用户清单
        public ObservableCollection<UserSelectable> Users { get; set; }

        public ICommand SelectedCommand { get; private set; }
        public ICommand SaveTopicCommand { get; private set; }
        public ICommand RefreshTopicCommand { get; private set; }
        public ICommand RefreshRoleCommand { get; private set; }
        public ICommand SaveUserCommand { get; private set; }
        public ICommand RefreshUserCommand { get; private set; }
    }
}